home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / SK (Sockects) 1.4.1 r2 / SK v1.4.1 r2.sit / SK 1.4.1 r2 / SK / SK Sources / SK_NetDB.cc < prev    next >
Text File  |  1994-06-16  |  20KB  |  826 lines

  1. /***************************************************************************
  2. * Copyright ⌐ 1992-1994 Matthias Neeracher and the Decision Systems Group
  3. * Permission is granted to anyone to use this software for any purpose on
  4. * any computer system, and to redistribute it freely, subject to the
  5. * following restrictions:
  6. * 1) The authors and the Decision Systems Group are not responsible for 
  7. *    the direct or indirect consequences of use of this software, no matter 
  8. *    how awful, even if they arise from defects in the software itself.
  9. *    This restriction applies to the use of this and any derived source code 
  10. *    and also to the use of all binary produced from this and any derived 
  11. *    source code.
  12. * 2) The origin and copyrights of this software must not be misrepresented, 
  13. *    either by explicit claim or by omission or alteration of copyright or
  14. *    authorship header information in this file or in any derived file.
  15. * 3) Altered or derived versions must be plainly marked as such, and must not
  16. *    be misrepresented as being the original software.
  17. * We encourage users of this software to provide feedback, bug fixes,
  18. * and enhancements to the authors for incorporation into future releases.
  19. *
  20. * ==========================================================================
  21. * FILE: SK_NetDB.cc
  22. * AUTHOR: Matthias Neeracher and Stephan Deibel
  23. * CREATION DATE: 12Sep92
  24. * VERSION: 13Jun94
  25. * DESCRIPTION: 
  26. *
  27. * Conversion routines for internet names and addresses
  28. * Gethostbyname() and gethostbyaddr() each return a pointer to an
  29. * object with the following structure describing an Internet
  30. * host referenced by name or by address, respectively. This
  31. * structure contains the information obtained from the MacTCP
  32. * name server.
  33. *
  34. * struct hostent
  35. * {
  36. *      char * h_name;
  37. *      char ** h_aliases;
  38. *      int  h_addrtype;
  39. *      int  h_length;
  40. *      char ** h_addr_list;
  41. * };
  42. * #define h_addr h_addr_list[0]
  43. *
  44. * The members of this structure are:
  45. *
  46. * h_name       Official name of the host.
  47. *
  48. * h_aliases    A zero terminated array of alternate names for the host.
  49. *
  50. * h_addrtype   The type of address being returned; always AF_INET.
  51. *
  52. * h_length     The length,in bytes, of the address.
  53. *
  54. * h_addr_list  A zero terminated array of network addresses for the host.
  55. *
  56. * Error return status from () and gethostbyaddr() is
  57. * indicated by return of a null pointer.  The external integer
  58. * h_errno may then be  checked  to  see  whether  this  is  a
  59. * temporary  failure  or  an  invalid  or  unknown  host.  The
  60. * routine herror  can  be  used  to  print  an error  message
  61. * describing the failure.  If its argument string is non-NULL,
  62. * it is printed, followed by a colon and a space.   The  error
  63. * message is printed with a trailing newline.
  64. *
  65. * h_errno can have the following values:
  66. *
  67. *   HOST_NOT_FOUND  No such host is known.
  68. *
  69. *   TRY_AGAIN        This is usually a temporary error and
  70. *                    means   that  the  local  server  did  not
  71. *                    receive a response from  an  authoritative
  72. *                    server.   A  retry at some later time may
  73. *                    succeed.
  74. *
  75. *   NO_RECOVERY        Some unexpected server failure was encountered.
  76. *                     This is a non-recoverable error.
  77. *
  78. *   NO_DATA            The requested name is valid but  does  not
  79. *                    have   an IP  address;  this  is not  a
  80. *                    temporary error. This means that the  name
  81. *                    is known  to the name server but there is
  82. *                    no address  associated  with  this  name.
  83. *                    Another type of request to the name server
  84. *                    using this domain name will result in  an
  85. *                    answer;  for example, a mail-forwarder may
  86. *                    be registered for this domain.
  87. *                    (NOT GENERATED BY THIS IMPLEMENTATION)
  88. * NOTES: 
  89. * 0) This code was derived from Matthias Neerarcher's GUSI 1.1.0 and
  90. *    the socket library written by Charlie Reiman (creiman@ncsa.uiuc.edu)
  91. *    and Tom Milligan (milligan@madhaus.utcs.utoronto.ca); Copyrights
  92. *    are subject to this origin.
  93. *
  94. * TO DO:
  95. *
  96. * 0) Remove use of globals for building return values?
  97. *
  98. * MODIFICATIONS: 
  99. * --------------------------------------------------------------------------
  100. * Date     Name      Description of modification
  101. * --------------------------------------------------------------------------
  102. * 14Sep92    MN       Maybe it works, maybe it doesn't
  103. * 21Nov92    MN       Remove force_active
  104. * 19Jan93    MN       Can't set aliases to NULL.
  105. * 13Jul93    SD       Port to THINK C++ 6.0
  106. * 21Jul93    SD       Subsetted to only TCP/UDP, applied DSG naming 
  107. *                    conventions and commenting guidelines, and
  108. *                    changed name to "SK" for clear distinction from
  109. *                    the GUSI code from which this was derived
  110. * 13Jun94   SD       Updated based on relevant changes to GUSI (through 1.4.1)
  111. */
  112.  
  113. #include "SK_INET_P.hh"
  114.  
  115. #include "Folders.h"
  116. #include "SK_Utilities_P.h"
  117.  
  118.  
  119. /**************************************************************************/ 
  120. /**************************************************************************/ 
  121. /* CONSTANTS */
  122.  
  123. #define MAXALIASES 0
  124.  
  125.  
  126. /**************************************************************************/ 
  127. /**************************************************************************/ 
  128. /* GLOBALS */
  129.  
  130. /* The global error value used by () and gethostbyaddr() */
  131. /* (declared in <netdb.h>) */
  132. int h_errno;
  133.  
  134. /* Global Macintosh hostInfo for DNS query returns */
  135. static struct hostInfo SKg_MacHost;
  136.  
  137. /* Global alias pointers for DNS query returns */
  138. static char *SKg_AliasPtrs[MAXALIASES+1] = {NULL};
  139.  
  140. /* Global address pointers for DNS query returns */
  141. static ip_addr *SKg_AddrPtrs[NUM_ALT_ADDRS+1];
  142.  
  143. /* Global used to collect other (Mac-specific) globals into a Unix hostent structure */
  144. static struct hostent SKg_UnixHost =
  145. {
  146.     SKg_MacHost.cname,
  147.     SKg_AliasPtrs,
  148.     AF_INET,
  149.     sizeof(ip_addr),
  150.     (char **) SKg_AddrPtrs
  151. };
  152.  
  153.  
  154. /**************************************************************************/ 
  155. /**************************************************************************/ 
  156. /* FUNCTIONS */
  157.  
  158.  
  159. /****************************************************************************
  160. * FUNCTION:
  161. *
  162. * DNRDone
  163. *
  164. * DESCRIPTION:
  165. *
  166. * Callback function used to change state when done waiting for DNR
  167. *
  168. * PARAMETERS:
  169. *
  170. * struct hostInfo *            -- The MacTCP hostInfo structure with DNR result
  171. * Boolean *                    -- Pointer to boolean indicating that DNR is done
  172. *
  173. */
  174.  
  175. pascal void DNRDone(struct hostInfo *, Boolean * done)
  176. {
  177.     *done = true;
  178. }
  179.  
  180.  
  181. /*************************************************************************** *
  182. * FUNCTION:
  183. *
  184. * make_in_addr
  185. *
  186. * DESCRIPTION:
  187. *
  188. * Make an in_addr out of a given ip_addr
  189. *
  190. * PARAMETERS:
  191. *
  192. * ip_addr        -- The given ip_addr
  193. *
  194. * RETURNS:
  195. *
  196. * in_addr        -- The resulting in_addr
  197. *
  198. */
  199.  
  200. inline struct in_addr make_in_addr(ip_addr addr)
  201. {
  202.     struct in_addr    res;
  203.  
  204.     res.s_addr    =    addr;
  205.  
  206.     return res;
  207. }
  208.  
  209.  
  210. /*************************************************************************** *
  211. * FUNCTION:
  212. *
  213. * gethostbyname
  214. *
  215. * DESCRIPTION:
  216. *
  217. * Find the ip address(es) and list of aliases of an internet host using 
  218. * one of its internet names.
  219. *
  220. * PARAMETERS:
  221. *
  222. * char *            -- The internet name in standard dotted internet name format
  223. *                       (e.g., dsg.harvard.edu)
  224. *
  225. * RETURNS:
  226. *
  227. * struct hostent *    -- The hostent structure containing the result of the query
  228. *                       (or NULL on error)
  229. *
  230. */
  231.  
  232. struct hostent * gethostbyname(char *name)
  233. {
  234.     Boolean done;
  235.     int i;
  236.  
  237.     if (SKg_INETSockets.Resolver()) {
  238.         h_errno = NO_RECOVERY;    
  239.         return NULL;
  240.     }
  241.     
  242.     for (i=0; i<NUM_ALT_ADDRS; i++)
  243.         SKg_MacHost.addr[i] = 0;
  244.  
  245.     done = false;
  246.  
  247.     if (StrToAddr(name, &SKg_MacHost, ResultProcPtr(DNRDone), (char *) &done) == cacheFault)
  248.         SPINP(!done,SKk_NAME,0L);
  249.  
  250.     switch (SKg_MacHost.rtnCode) {
  251.         case noErr: break;
  252.  
  253.         case nameSyntaxErr:        h_errno = HOST_NOT_FOUND;    return(NULL);
  254.         case cacheFault:        h_errno = NO_RECOVERY;        return(NULL);
  255.         case noResultProc:        h_errno = NO_RECOVERY;        return(NULL);
  256.         case noNameServer:        h_errno = HOST_NOT_FOUND;    return(NULL);
  257.         case authNameErr:        h_errno = HOST_NOT_FOUND;    return(NULL);
  258.         case noAnsErr:            h_errno = TRY_AGAIN;        return(NULL);
  259.         case dnrErr:            h_errno = NO_RECOVERY;        return(NULL);
  260.         case outOfMemory:        h_errno = TRY_AGAIN;        return(NULL);
  261.         default:                h_errno = NO_RECOVERY;        return(NULL);
  262.     }
  263.  
  264.     /* was the 'name' an IP address? */
  265.     if (SKg_MacHost.cname[0] == 0) {
  266.         h_errno = HOST_NOT_FOUND;
  267.         return(NULL);
  268.     }
  269.  
  270.     /* for some reason there is a dot at the end of the name */
  271.     i = strlen(SKg_MacHost.cname) - 1;
  272.     if (SKg_MacHost.cname[i] == '.')
  273.         SKg_MacHost.cname[i] = 0;
  274.  
  275.     for (i=0; i<NUM_ALT_ADDRS && SKg_MacHost.addr[i]!=0; i++)
  276.         SKg_AddrPtrs[i] =    (ip_addr *) &SKg_MacHost.addr[i];
  277.  
  278.     SKg_AddrPtrs[i] = NULL;
  279.  
  280.     return &SKg_UnixHost;
  281. }
  282.  
  283.  
  284. /*************************************************************************** *
  285. * FUNCTION:
  286. *
  287. * gethostbyaddr
  288. *
  289. * DESCRIPTION:
  290. *
  291. * Find the ip address(es) and list of aliases of an internet host using 
  292. * the host's internet number.
  293. *
  294. * PARAMETERS:
  295. *
  296. * struct in_addr *        -- The internet address of the host
  297. * int                    -- unused
  298. * int                    -- unused
  299. *
  300. * RETURNS:
  301. *
  302. * struct hostent *        -- The hostent structure containing the result of the query
  303. *                           (or NULL on error)
  304. *
  305. */
  306.  
  307. struct hostent * gethostbyaddr(const char *addrP, int, int)
  308. {
  309.     Boolean    done;
  310.     int i;
  311.  
  312.     if (SKg_INETSockets.Resolver()) {
  313.         h_errno = NO_RECOVERY;    
  314.         return NULL;
  315.     }
  316.  
  317.     for (i=0; i<NUM_ALT_ADDRS; i++)
  318.         SKg_MacHost.addr[i] = 0;
  319.  
  320.     done = false;
  321.  
  322.     if (AddrToName(*(ip_addr *)addrP, &SKg_MacHost, ResultProcPtr(DNRDone), (char *) &done) == cacheFault)
  323.         SPINP(!done,SKk_ADDR,0L);
  324.  
  325.     switch (SKg_MacHost.rtnCode) {
  326.     case noErr:             break;
  327.  
  328.     case cacheFault:        h_errno = NO_RECOVERY;        return(NULL);
  329.     case noNameServer:        h_errno = HOST_NOT_FOUND;    return(NULL);
  330.     case authNameErr:        h_errno = HOST_NOT_FOUND;    return(NULL);
  331.     case noAnsErr:            h_errno = TRY_AGAIN;        return(NULL);
  332.     case dnrErr:            h_errno = NO_RECOVERY;        return(NULL);
  333.     case outOfMemory:        h_errno = TRY_AGAIN;        return(NULL);
  334.     default:                h_errno = NO_RECOVERY;        return(NULL);
  335.     }
  336.  
  337.     /* for some reason there is a dot at the end of the name */
  338.     i = strlen(SKg_MacHost.cname) - 1;
  339.     if (SKg_MacHost.cname[i] == '.')
  340.         SKg_MacHost.cname[i] = 0;
  341.  
  342.     for (i=0; i<NUM_ALT_ADDRS; i++)
  343.         SKg_AddrPtrs[i] = (ip_addr *) &SKg_MacHost.addr[i];
  344.  
  345.     SKg_AddrPtrs[NUM_ALT_ADDRS] = NULL;
  346.  
  347.     return &SKg_UnixHost;
  348. }
  349.  
  350.  
  351. /*************************************************************************** *
  352. * FUNCTION:
  353. *
  354. * inet_ntoa
  355. *
  356. * DESCRIPTION:
  357. *
  358. * Convert a given internet address to the official fully qualified host
  359. * name for that address
  360. *
  361. * PARAMETERS:
  362. *
  363. * struct in_addr        -- The internet address of the host
  364. *
  365. * RETURNS:
  366. *
  367. * char *                -- The fully qualified name in standard dotted format
  368. *                           (e.g., dsg.harvard.edu)
  369. *
  370. */
  371.  
  372. extern "C" {
  373.  
  374. char * inet_ntoa(struct in_addr inaddr)
  375. {
  376.     if (SKg_INETSockets.Resolver()) {
  377.         h_errno = NO_RECOVERY;    
  378.         return NULL;
  379.     }
  380.     
  381.     (void) AddrToStr(inaddr.s_addr, SKg_MacHost.cname);
  382.  
  383.     return SKg_MacHost.cname;
  384. }
  385.  
  386. }  /* extern "C" */
  387.  
  388.  
  389. /*************************************************************************** *
  390. * FUNCTION:
  391. *
  392. * inet_addr
  393. *
  394. * DESCRIPTION:
  395. *
  396. * ???
  397. *
  398. * PARAMETERS:
  399. *
  400. * char *            -- ???
  401. *
  402. * RETURNS:
  403. *
  404. * struct in_addr    -- ???
  405. *
  406. */
  407.  
  408. extern "C" {
  409.  
  410. struct in_addr inet_addr(char *address)
  411. {
  412.     if (SKg_INETSockets.Resolver()) {
  413.         h_errno = NO_RECOVERY;    
  414.         return make_in_addr(0xFFFFFFFF);
  415.     }
  416.     
  417.     if (StrToAddr(address,&SKg_MacHost,NULL,NULL) != noErr)
  418.         return make_in_addr(0xFFFFFFFF);
  419.  
  420.     /* was the 'address' really a name? */
  421.     if (SKg_MacHost.cname[0] != 0)
  422.         return make_in_addr(0xFFFFFFFF);
  423.  
  424.     return make_in_addr(SKg_MacHost.addr[0]);
  425. }
  426.  
  427. }  /* extern "C" */
  428.  
  429.  
  430. /*************************************************************************** *
  431. * FUNCTION:
  432. *
  433. * gethostname
  434. *
  435. * DESCRIPTION:
  436. *
  437. * Get host name (in standard dotted format, e.g. dsg.harvard.edu) for
  438. * this Macintosh.  If DNS query fails, the IP address of this Mac is
  439. * returned in ascii format.
  440. *
  441. * PARAMETERS:
  442. *
  443. * char *        -- Pointer to buffer for return value
  444. * long            -- Length of above buffer
  445. *
  446. * RETURNS:
  447. *
  448. * int            -- Error return (0 = no error)
  449. *
  450. * NOTES:
  451. *
  452. * Returning ip address upon query failure is non-standard but necessary
  453. * because many Macs do not have officially registered names.
  454. *
  455. */
  456.  
  457. int gethostname(char *machname, long buflen)
  458. {
  459.     in_addr ipaddr;
  460.     struct    hostent *hp;
  461.     struct GetAddrParamBlock pbr;
  462.  
  463.     pbr.ioCRefNum = SKg_INETSockets.Driver();
  464.     pbr.csCode = ipctlGetAddr;
  465.  
  466.     if (PBControlSync(ParmBlkPtr(&pbr)))
  467.         goto resign;
  468.  
  469.     ipaddr = make_in_addr(pbr.ourAddress);
  470.  
  471.     hp = gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
  472.  
  473.     if (!hp)
  474.         goto resign;
  475.     else
  476.         strncpy(machname, hp->h_name, unsigned(buflen));
  477.  
  478.     machname[buflen-1] = 0;  /* extra safeguard */
  479.  
  480.     return 0;
  481.  
  482.     /*****/
  483.     resign:
  484.     sprintf(machname, "%d.%d.%d.%d",
  485.                             ipaddr.s_addr>>24,
  486.                             ipaddr.s_addr>>16 & 0xff,
  487.                             ipaddr.s_addr>>8 & 0xff,
  488.                             ipaddr.s_addr & 0xff);
  489.     return 0;
  490. }
  491.  
  492.  
  493. /****************************************************************************
  494. * LOCAL UTILITIES AND SUPPORT FOR SERVICES TABLE */
  495.  
  496. static char *SKg_ServicesList[] =
  497. {
  498.     "echo            7/udp",
  499.     "discard        9/udp",
  500.     "time           37/udp",
  501.     "domain            53/udp",
  502.     "sunrpc            111/udp",
  503.     "tftp            69/udp",
  504.     "biff           512/udp",
  505.     "who            513/udp",
  506.     "talk           517/udp",
  507.     "ftp-data           20/tcp",
  508.     "ftp               21/tcp",
  509.     "telnet           23/tcp",
  510.     "smtp               25/tcp",
  511.     "time              37/tcp",
  512.     "whois          43/tcp",
  513.     "domain          53/tcp",
  514.     "hostnames      101/tcp",
  515.     "nntp           119/tcp",
  516.     "finger           79/tcp",
  517.     "ntp               123/tcp",
  518.     "uucp           540/tcp",
  519.     NULL
  520.   };
  521.  
  522. /* Globals for managing services */
  523. static char                 SKg_ServicesLine[128];
  524. static struct servent        SKg_ServicesEntry;
  525. static FILE *                 SKg_ServicesFile;
  526. static int                    SKg_ServicesPtr;
  527. static char *                SKg_ServicesAliases[8];
  528. static int                    SKg_ServicesStay = 0;
  529.   
  530. /* Local utility */
  531. void setservent(int stayopen)
  532. {
  533.     if (SKg_ServicesFile && SKg_ServicesFile != (FILE *) -1) {
  534.         rewind(SKg_ServicesFile);
  535.     }
  536.     SKg_ServicesPtr    = 0;
  537.     SKg_ServicesStay = SKg_ServicesStay || stayopen;
  538. }
  539.  
  540. /* Local utility */
  541. void endservent()
  542. {
  543.     if (SKg_ServicesFile && SKg_ServicesFile != (FILE *) -1) {
  544.         fclose(SKg_ServicesFile);
  545.         SKg_ServicesFile = NULL;
  546.     }
  547.     
  548.     SKg_ServicesStay = 0;
  549. }
  550.  
  551. /* Local utility */
  552. struct servent *  getservent()
  553. {
  554.     char *    p;
  555.     int        aliascount;
  556.     
  557.     if (!SKg_ServicesFile) {
  558.         short vRefNum;
  559.         long parID;
  560.         Str255 name = "\p/etc/services";
  561.         Str255 fullpath;
  562.         OSErr err;
  563.         
  564.         if (!FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, 
  565.                         &vRefNum, &parID)) {
  566.             
  567.             err = SK_FileRefToFullPath(vRefNum, parID, name, fullpath);
  568.             if (err != noErr)
  569.                 goto retry;
  570.             
  571.             SK_PtoCstr((char *) fullpath);
  572.             
  573.             SKg_ServicesFile = fopen((char *) fullpath, "r");
  574.             if (SKg_ServicesFile != NULL)
  575.                 goto retry;
  576.         }    
  577.         SKg_ServicesFile = (FILE *) -1;
  578.         SKg_ServicesPtr    = 0;
  579.       }
  580.     
  581. retry:
  582.     if (SKg_ServicesFile == (FILE *) -1)
  583.         if (!SKg_ServicesList[SKg_ServicesPtr])
  584.             return (struct servent *) NULL;
  585.         else
  586.             strcpy(SKg_ServicesLine, SKg_ServicesList[SKg_ServicesPtr++]);
  587.             
  588.     else if (!(fgets(SKg_ServicesLine, 128, SKg_ServicesFile)))
  589.         return (struct servent *) NULL;
  590.     
  591.     p = strpbrk(SKg_ServicesLine, "#\n");
  592.     if (p != NULL)
  593.         *p = 0;
  594.         
  595.     if (!SKg_ServicesLine[0])
  596.         goto retry;
  597.     
  598.     SKg_ServicesEntry.s_name = strtok(SKg_ServicesLine, " \t");
  599.     if (SKg_ServicesEntry.s_name == NULL)
  600.         goto retry;
  601.         
  602.     p = strtok(NULL, " \t");
  603.     if (p == NULL)
  604.         goto retry;
  605.     
  606.     SKg_ServicesEntry.s_proto = strpbrk(p, "/,");
  607.     if (SKg_ServicesEntry.s_proto == NULL)
  608.         goto retry;
  609.         
  610.     *SKg_ServicesEntry.s_proto++     = 0;
  611.     SKg_ServicesEntry.s_port         = htons(atoi(p));
  612.     SKg_ServicesEntry.s_aliases     = SKg_ServicesAliases;
  613.     
  614.     for (aliascount = 0; aliascount < 7; ) {
  615.         SKg_ServicesAliases[aliascount++] = strtok(NULL, " \t");
  616.         if (SKg_ServicesAliases[aliascount++] == NULL)
  617.             break;
  618.     }
  619.     
  620.     SKg_ServicesAliases[aliascount] = NULL;
  621.     
  622.     return &SKg_ServicesEntry;
  623. }
  624.  
  625.  
  626. /*************************************************************************** *
  627. * FUNCTION:
  628. *
  629. * getservbyname
  630. *
  631. * DESCRIPTION:
  632. *
  633. * Get a servent structure containing information about a given named
  634. * internet service.
  635. *
  636. * PARAMETERS:
  637. *
  638. * const char *        -- The null-terminated name of the desired internet service
  639. * const char *        -- Protocol to use (must be 'udp' or 'tcp')
  640. *
  641. * RETURNS:
  642. *
  643. * struct servent *    -- Pointer to structure containing the official name, port number
  644. *                       and aliases of the given internet service
  645. *
  646. */
  647.  
  648. struct servent * getservbyname(const char * name, const char * proto)
  649. {
  650.     struct servent *     ent;
  651.     char **                 al;
  652.     setservent(0);
  653.     
  654.     while (ent = getservent()) {
  655.         if (!strcmp(name, ent->s_name))
  656.             goto haveName;
  657.         
  658.         for (al = ent->s_aliases; *al; ++al)
  659.             if (!strcmp(name, *al))
  660.                 goto haveName;
  661.         
  662.         continue;
  663. haveName:
  664.         if (!proto || !strcmp(proto, ent->s_proto))
  665.             break;
  666.     }
  667.     
  668.     if (!SKg_ServicesStay)
  669.         endservent();
  670.     
  671.     return ent;
  672. }
  673.  
  674.  
  675. /*************************************************************************** *
  676. * FUNCTION:
  677. *
  678. * getservbyport
  679. *
  680. * DESCRIPTION:
  681. *
  682. * Get a servent structure containing information about a service running
  683. * on a given port.
  684. *
  685. * PARAMETERS:
  686. *
  687. * int            -- The port number
  688. * const char *    -- Protocol name (must be 'udp' or 'tcp')
  689. *
  690. * RETURNS:
  691. *
  692. * struct servent *    -- Pointer to structure containing the official name,
  693. *                       port number, and aliases of the given internet service
  694. *
  695. */
  696.  
  697. struct servent * getservbyport(int port, const char * proto)
  698. {
  699.     struct servent * ent;
  700.     
  701.     setservent(0);
  702.     
  703.     while (ent = getservent())
  704.         if (port == ent->s_port && (!proto || !strcmp(proto, ent->s_proto)))
  705.             break;
  706.     
  707.     if (!SKg_ServicesStay)
  708.         endservent();
  709.     
  710.     return ent;
  711.   }
  712.   
  713.  
  714. /*************************************************************************** *
  715. * FUNCTION:
  716. *
  717. * getprotobyname
  718. *
  719. * DESCRIPTION:
  720. *
  721. * Get a protoent structure containing information about a given named
  722. * internet protocol.
  723. *
  724. * PARAMETERS:
  725. *
  726. * char *            -- Protocol name (must be 'udp' or 'tcp')
  727. *
  728. * RETURNS:
  729. *
  730. * struct protoent *    -- Pointer to structure containing the official name, 
  731. *                      aliases, and protocol number for the given protocol
  732. *
  733. * NOTES:
  734. *
  735. */
  736.  
  737. /* Kludge globals for return values */
  738. static char SKg_TCP[] = "tcp";
  739. static char SKg_UDP[] = "udp";
  740.  
  741. /* Maximum number of protocol aliases */
  742. #define    SKk_MaxProtocolEntries 10
  743.  
  744. /* Globals for accumulating return values for calls to getprotobyname() */
  745. static struct protoent SKg_ProtocolEntries[SKk_MaxProtocolEntries];
  746. static int SKg_ProtocolEntriesCount=0;
  747.  
  748. struct protoent * getprotobyname(const char * name)
  749. {
  750.     struct protoent *pe;
  751.  
  752.     pe = &SKg_ProtocolEntries[SKg_ProtocolEntriesCount];
  753.     if (strcmp(name, "udp") == 0) {
  754.         pe->p_name = SKg_UDP;
  755.         pe->p_proto = IPPROTO_UDP;
  756.     } else if (strcmp (name, "tcp") == 0)  {
  757.         pe->p_name = SKg_TCP;
  758.         pe->p_proto = IPPROTO_TCP;
  759.     } else {
  760.         errno = EPROTONOSUPPORT;
  761.         return NULL;
  762.     }
  763.     pe->p_aliases = SKg_AliasPtrs;
  764.     SKg_ProtocolEntriesCount = (SKg_ProtocolEntriesCount +1) % SKk_MaxProtocolEntries;
  765.     return pe;
  766. }
  767.  
  768.  
  769. /*************************************************************************** *
  770. * FUNCTION:
  771. *
  772. * get_myaddress()
  773. *
  774. * DESCRIPTION:
  775. *
  776. * Get the socket internet address for this process.
  777. *
  778. * PARAMETERS:
  779. *
  780. * struct sockaddr_in *    -- Buffer space for the return value.
  781. *
  782. * RETURNS:
  783. *
  784. * The address family, address, and port (???) for this process.
  785. *
  786. * NOTES:
  787. *
  788. * Currently, this always returns the sin_port and sin_len fields
  789. * set to 0.  Not sure what these should be!
  790. *
  791. */
  792.  
  793. void get_myaddress(struct sockaddr_in *addr)
  794. {
  795.     struct in_addr ipaddr;
  796.     struct GetAddrParamBlock pbr;
  797.  
  798.     pbr.ioCRefNum = SKg_INETSockets.Driver();
  799.     pbr.csCode = ipctlGetAddr;
  800.  
  801.     if (PBControlSync(ParmBlkPtr(&pbr)))
  802.         return; /* Failure handling ? */
  803.  
  804.     ipaddr = make_in_addr(pbr.ourAddress);
  805.  
  806.     addr->sin_len = 0;    /* ?? */
  807.     addr->sin_family = AF_INET;
  808.     addr->sin_port = 0;   /* ?? */
  809.     memcpy(&(addr->sin_addr), &ipaddr, sizeof(struct in_addr));
  810. }
  811.  
  812.